package http

import (
	"context"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/rs/zerolog"
	nhttp "net/http"
	"os"
	"time"
)

type Server struct {
	log          *zerolog.Logger
	http         *nhttp.Server
	cancelServer []func()
}

func (s *Server) RegisterCancelServer(cancel func()) {
	s.cancelServer = append(s.cancelServer, cancel)
}

func (s *Server) Start(quit <-chan os.Signal) {
	s.log.Info().Msgf("http Server %s Start", s.http.Addr)
	go func() {
		if err := s.http.ListenAndServe(); err != nil && !errors.Is(err, nhttp.ErrServerClosed) {
			s.log.Error().Msgf("http Server Shutdown: %s", err)
			os.Exit(1)
		}
	}()

	<-quit
	s.log.Info().Msg("Shutdown http Server")

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	if err := s.http.Shutdown(ctx); err != nil {
		s.log.Error().Msgf("http Server Shutdown: %s", err)
	}

	//循环去取消其他服务
	for _, h := range s.cancelServer {
		h()
	}

	s.log.Info().Msg("http Server Stop")
}

func NewServer(conf Conf, log *zerolog.Logger, router *gin.Engine) *Server {

	l := log.With().Str("type", "httpServer").Logger()
	return &Server{
		log:          &l,
		cancelServer: make([]func(), 0),
		http: &nhttp.Server{
			Addr:    conf.Addr,
			Handler: router,
		},
	}
}
